#include <iostream>
#include "Object.h"
#include "ObjPtr.h"
#pragma warning( disable : 4355 )	// to use 'this' in an initializer list

class Player : public Object
{
public:
	Player(const std::string& name) : Object(name){}
};


class Rocket : public Object
{ 
public:
	Rocket(const std::string& name) : 
	  Object(name), 
	  target(this, 0)
	{}
	void setTarget(Player* player)
	{
		target = player;
	}

	Player* getTarget() const 
	{
		return target;
	}
private:
	ObjPtr<Player> target;
};


void printRocketInfo(std::ostream& out, const Rocket* rocket)
{
	out << rocket->getName() << ": ";
	Player* target = rocket->getTarget();
	if(target) out << "my target is " << target->getName() << std::endl;
	else out << "I don't have a target" << std::endl;
}

void printPlayerInfo(std::ostream& out, const Player* player)
{
	out << player->getName() << ": omg! rockets - ";
	for(Object::outer_iterator it = player->outer_begin(); it != player->outer_end(); it++)
	{
		Object* obj = (*it);
		if(dynamic_cast<Rocket*>(obj)) out << obj->getName() << "  ";
	}
	out << std::endl;
}


int main()
{
	Player* player = new Player("Player");
	Rocket*  rocket1 = new Rocket("Rocket1");
	Rocket*  rocket2 = new Rocket("Rocket2");
	rocket1->setTarget(player);
	rocket2->setTarget(player);
	printRocketInfo(std::cout, rocket1);
	printRocketInfo(std::cout, rocket2);
	printPlayerInfo(std::cout, player);

	std::cout << "----------------" << std::endl;
	std::cout << "Lets kill Player" << std::endl;
	delete player;
	printRocketInfo(std::cout, rocket1);
	printRocketInfo(std::cout, rocket2);
	delete rocket1;
	delete rocket2;
}
